const Config  = require('./../config/base_config.js')
const Storage  = require('./../utils/storage.js')

const BASE_URL = Config.API_HOST;

class Request {
  constructor() {
    this.interceptors = {
      request: [],
      response: [],
    };
    this.pendingRequests = new Set();
    this.isRefreshingToken = false;
    this.loadingTimer = null;
  }

  // 添加请求拦截器
  useRequestInterceptor(fulfilled, rejected) {
    this.interceptors.request.push({ fulfilled, rejected });
  }

  // 添加响应拦截器
  useResponseInterceptor(fulfilled, rejected) {
    this.interceptors.response.push({ fulfilled, rejected });
  }

  // 显示带超时的loading
  showLoadingWithTimeout() {
    wx.showLoading({
      title: '加载中...',
      mask: true
    });
    
    // 10秒后自动隐藏loading
    this.loadingTimer = setTimeout(() => {
      wx.hideLoading();
    }, 10000);
  }

  // 清除用户数据
  clearUserData() {
    Storage.remove('access_token');
    Storage.remove('refresh_token');
    Storage.remove('userInfo');
  }

  // 跳转到登录页
  navigateToLogin() {
    const pages = getCurrentPages();
    const currentRoute = pages[pages.length - 1].route;
    
    if (!currentRoute.includes('login')) {
      wx.redirectTo({
        url: '/pages/login/index'
      });
    }
  }

  // 处理HTTP错误状态码
  handleHttpError(statusCode) {
    // 先清除loading和定时器
    wx.hideLoading();
    if (this.loadingTimer) {
      clearTimeout(this.loadingTimer);
      this.loadingTimer = null;
    }

    const errorMap = {
      400: '请求参数错误',
      401: '登录已过期，请重新登录',
      403: '拒绝访问',
      404: '请求地址不存在',
      500: '服务器内部错误',
      502: '网关错误',
      503: '服务不可用',
      504: '网关超时'
    };

    wx.showToast({
      title: errorMap[statusCode] || `请求失败，状态码: ${statusCode}`,
      icon: 'none',
      duration: 2000,
      mask: true
    });

    // 401处理 - 延迟跳转
    if (statusCode === 401) {
      setTimeout(() => {
        this.clearUserData();
        this.navigateToLogin();
      }, 2000);
    }
  }

  // 封装wx.request为Promise
  wxRequest(config) {
    return new Promise((resolve, reject) => {
      wx.request({
        ...config,
        success: (res) => {
          resolve(res);
        },
        fail: (err) => {
          reject(err);
        }
      });
    });
  }

  // 处理响应数据
  async processResponse(response) {
    let res = response;
    
    // 响应拦截器处理
    for (const interceptor of this.interceptors.response) {
      res = await interceptor.fulfilled(res) || res;
    }

    if (res.statusCode === 200) {
      if (res.data.code === 0 || res.data.success) {
        return res.data;
      } else {
        throw { 
          type: 'business', 
          message: res.data.message || '请求失败',
          data: res.data 
        };
      }
    } else {
      throw { 
        type: 'http', 
        statusCode: res.statusCode,
        data: res 
      };
    }
  }

  // 处理请求错误
  handleRequestError(error) {
    // 确保loading被清除
    wx.hideLoading();
    if (this.loadingTimer) {
      clearTimeout(this.loadingTimer);
      this.loadingTimer = null;
    }

    if (error.type === 'http') {
      this.handleHttpError(error.statusCode);
    } else {
      wx.showToast({
        title: error.message || '请求失败',
        icon: 'none',
        duration: 2000
      });
    }
  }

  // Token刷新逻辑
  async refreshToken() {
    if (this.isRefreshingToken) {
      return new Promise(resolve => {
        const checkInterval = setInterval(() => {
          if (!this.isRefreshingToken) {
            clearInterval(checkInterval);
            resolve();
          }
        }, 200);
      });
    }

    this.isRefreshingToken = true;
    try {
      const refreshToken = Storage.get('refresh_token');
      console.log(refreshToken)
      const result = await this.post('/auth/refresh', { refresh_token: refreshToken });
      
      Storage.set('access_token', result.access_token);
      if (result.refresh_token) {
        Storage.set('refresh_token', result.refresh_token);
      }
      return result;
    } finally {
      this.isRefreshingToken = false;
    }
  }

  // 带重试机制的请求
  async requestWithRetry(url, options = {}, retries = 1) {
    const requestKey = `${url}_${JSON.stringify(options)}`;
    this.pendingRequests.add(requestKey);

    try {
      // 请求拦截器处理
      let config = {
        url: `${BASE_URL}${url}`,
        method: options.method || 'GET',
        data: options.data || {},
        header: {
          'content-type': 'application/json',
          'Authorization': `Bearer ${Storage.get("access_token") || ''}`,
          ...options.header
        },
        timeout: options.timeout || 60000
      };

      for (const interceptor of this.interceptors.request) {
        config = await interceptor.fulfilled(config) || config;
      }

      this.showLoadingWithTimeout();

      try {
        const response = await this.wxRequest(config);
        const processedResponse = await this.processResponse(response);
        return processedResponse;
      } catch (error) {
        // Token过期自动刷新
        if (error.statusCode === 401 && retries > 0) {
          await this.refreshToken();
          return this.requestWithRetry(url, options, retries - 1);
        }
        throw error;
      }
    } catch (error) {
      this.handleRequestError(error);
      throw error;
    } finally {
      this.pendingRequests.delete(requestKey);
      wx.hideLoading();
      if (this.loadingTimer) {
        clearTimeout(this.loadingTimer);
        this.loadingTimer = null;
      }
    }
  }

  // 主请求方法
  async request(url, options = {}) {
    return this.requestWithRetry(url, options);
  }

  // 快捷方法
  get(url, data, options = {}) {
    return this.request(url, {
      method: 'GET',
      data,
      ...options
    });
  }

  post(url, data, options = {}) {
    return this.request(url, {
      method: 'POST',
      data,
      ...options
    });
  }

  put(url, data, options = {}) {
    return this.request(url, {
      method: 'PUT',
      data,
      ...options
    });
  }

  delete(url, data, options = {}) {
    return this.request(url, {
      method: 'DELETE',
      data,
      ...options
    });
  }

  upload(url, filePath, name, formData = {}, options = {}) {
    const requestKey = `upload_${url}_${filePath}`;
    this.pendingRequests.add(requestKey);

    return new Promise((resolve, reject) => {
      this.showLoadingWithTimeout();

      wx.uploadFile({
        url: `${BASE_URL}${url}`,
        filePath,
        name,
        formData,
        header: {
          'Authorization': `Bearer ${Storage.get('access_token') || ''}`,
          ...options.header
        },
        success: (res) => {
          try {
            const data = res.statusCode === 200 ? JSON.parse(res.data) : res.data;
            if (res.statusCode === 200) {
              resolve(data);
            } else {
              this.handleHttpError(res.statusCode);
              reject(data);
            }
          } catch (e) {
            reject(e);
          }
        },
        fail: (err) => {
          this.handleRequestError(err);
          reject(err);
        },
        complete: () => {
          this.pendingRequests.delete(requestKey);
          wx.hideLoading();
          if (this.loadingTimer) {
            clearTimeout(this.loadingTimer);
            this.loadingTimer = null;
          }
        }
      });
    });
  }
}

// 创建实例
const http = new Request();

// 示例拦截器配置
http.useRequestInterceptor(
  (config) => {
    console.log('请求拦截器 - 请求前', config);
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

http.useResponseInterceptor(
  (response) => {
    console.log('响应拦截器 - 响应后', response);
    return response;
  },
  (error) => {
    if (error.statusCode === 403) {
      wx.showModal({
        title: '权限不足',
        content: '当前账号没有权限访问此功能',
        showCancel: false
      });
    }
    return Promise.reject(error);
  }
);

module.exports= http;